package org.spring.boot.fusion.auth.sso.config;

import java.util.List;

import org.spring.boot.fusion.auth.sso.filter.FusionOnlyUserFilter;
import org.spring.boot.fusion.auth.sso.filter.FusionPermissionsValidateFilter;
import org.spring.boot.fusion.auth.sso.handler.FusionLoginFailureHandler;
import org.spring.boot.fusion.auth.sso.handler.FusionLoginSuccessHandler;
import org.spring.boot.fusion.auth.sso.service.FusionPermissionsService;
import org.spring.boot.fusion.common.constant.ConstantAttribute;
import org.spring.boot.fusion.common.tools.ConcurrentTools;
import org.spring.boot.fusion.security.properties.FusionTokenProperties;
import org.spring.boot.fusion.security.tools.NotLoginAuthUrlTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableResourceServer
public class FusionTokenClientConfig extends ResourceServerConfigurerAdapter {

	@Autowired
	private FusionTokenProperties tokenProperties;
	@Autowired
	private FusionPermissionsService permissionsService;
	@Autowired
	private TokenStore tokenStore;
	@Autowired
	private FusionLoginSuccessHandler loginSuccessHandler;
	@Autowired
	private FusionLoginFailureHandler loginFailureHandler;
	@Autowired
	private UserDetailsService userDetailsService;
	@Autowired
	private FusionTokenProperties tokenConfigProperties;
	

	@Override
	public void configure(HttpSecurity http) throws Exception {
		//权限拦截
		FusionPermissionsValidateFilter permissionsValidateFilter = new FusionPermissionsValidateFilter();
		permissionsValidateFilter.setTokenProperties(tokenProperties);
		permissionsValidateFilter.setPermissionsService(permissionsService);
		//限制一个用户登陆
		FusionOnlyUserFilter fusionOnlyUserFilter = new FusionOnlyUserFilter();
		fusionOnlyUserFilter.setTokenStore(tokenStore);
		fusionOnlyUserFilter.setTokenConfigProperties(tokenConfigProperties);
		//权限拦截
		http.addFilterAfter(permissionsValidateFilter, UsernamePasswordAuthenticationFilter.class);
		//限制一个用户登陆
		http.addFilterBefore(fusionOnlyUserFilter, UsernamePasswordAuthenticationFilter.class);
		http
		// 设置表单登陆
		.formLogin()
		// 设置登录页（rest风格设置错误的登录页）
		.loginPage(tokenConfigProperties.getLoginErrorUrl())
		// 登陆的方法
		.loginProcessingUrl(tokenConfigProperties.getUserLoginUrl())
		// 登陆成功之后需要处理的方法
		.successHandler(loginSuccessHandler)
		// 登陆失败之后需要处理的方法
		.failureHandler(loginFailureHandler)
		//登陆的实现方法
		.and().userDetailsService(userDetailsService);
		
		// 设置请求拦截
		ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests = http
				.authorizeRequests();
		String[] noRelease = tokenProperties.getNoRelease();
		if(noRelease!=null && noRelease.length > 0) {
			for (String noReleaseUrl : noRelease) {
				if (noReleaseUrl != null && !noReleaseUrl.equalsIgnoreCase(ConstantAttribute.NULL) && noReleaseUrl.length() > 0) {
					authorizeRequests.antMatchers(noReleaseUrl).permitAll();
				}
			}
		}
		List<String> notAuthUrlList = NotLoginAuthUrlTools.getNotAuthUrlList(tokenProperties.getMethodsPackage());
		if(notAuthUrlList!=null && notAuthUrlList.size() > 0) {
			for (String notAuthUrl : notAuthUrlList) {
				authorizeRequests.antMatchers(notAuthUrl).permitAll();
			}
			ConcurrentTools.getConcurrentHashMap().put(ConstantAttribute.NOT_AUTH_URL_LIST,notAuthUrlList);
		}
		authorizeRequests.antMatchers(HttpMethod.OPTIONS).permitAll();
		authorizeRequests.antMatchers(tokenConfigProperties.getUserLoginUrl()).permitAll();
		authorizeRequests.antMatchers(tokenConfigProperties.getLoginErrorUrl()).permitAll();
		authorizeRequests.antMatchers(tokenConfigProperties.getTokenLogoutUrl()).permitAll();
		authorizeRequests.antMatchers(tokenConfigProperties.getRefreshTokenUrl()).permitAll();
		// 设置拦截所有的请求
		authorizeRequests.anyRequest().authenticated().and().csrf().disable();
	}

	@Override
	public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
		resources.tokenStore(tokenStore);
	}
	
}
